package cn.tedu.charging.order.consumer;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MqttClientCallback implements MqttCallbackExtended{
    /*
        方法作用: 当mqttClient调用connect并且成功和emqx建立通信之后立即调用
        参数:
        boolean reconnect: 如果本次建立的连接是重新连接,reconnect就是true 第一次连接false
        String serverURI: 连接服务端address tcp://192.168.8.100:1883
     */
    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        if (reconnect){
            log.info("重新链接成功,broker地址:{}",serverURI);
        }else{
            log.info("首次连接成功,broker地址:{}",serverURI);
        }
    }
    /*
        方法作用: 当mqttClient调用disconnect方法断开连接后,或者由于网络波动,
        导致和服务端连接通信超时失败,回调就会调用这个方法
        参数:
        Throwable cause: 断开连接的原因
     */
    @Override
    public void connectionLost(Throwable cause) {
        log.info("连接断开,原因:{}",cause);
    }
    /*
      方法作用: 当mqttClient发送消息的时候,只要消息成功发送到emqx,不管emqx是否能够接收到
      反馈接收成功还是失败,都会调用这个deliveryComplete,处理发送完成的业务
      qos服务质量级别中0 表示根本不关心投递发送结果,所以,如果客户端mqttClient使用qos=0级别发送消息,不会有任何异常
      不会回调这个方法
      参数:
      IMqttDeliveryToken token: 发送的消息对象 映射,包含了你发送消息的所有内容,以及双方通信的结果
    */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        //1.可以获取token的确认结果 ack(true表示emqx接收成功 false表示投递失败)
        boolean complete = token.isComplete();
        //如果发送时失败的,token会携带一个服务端异常反馈
        MqttException exception = token.getException();
        //2.判断消息投递结果
        if(complete&&exception==null){
            //发送结果是成功的
            log.info("消息发送成功");
        }else{
            //发送结果是失败的
            log.error("消息发送失败,原因:{}",exception);
        }
    }

    /**
     * 消费消息的入口 所有当前客户端监听订阅的主题消息都会进入这个方法处理
     * 方法作用: 当mqttClient连接对象订阅了某个主题,一旦这个主题中出现消息,
     * 就会通过这个方法将消息传递给客户端
     * 参数:
     * String topic: 消息来源的topic名称
     * MqttMessage message: 消息对象,包含了消息的所有内容
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.info("消息接收成功,消息:{},来源主题:{}",message,topic);
    }
}
